<template>
    <view
        ref="triggerRef"
        id="trigger"
        class="tooltip-wrapper"
        @mousedown="onStart"
        @mouseup="onEnd"
        @mouseleave="onCancel"
        @touchstart="onStart"
        @touchend="onEnd"
        @touchcancel="onCancel"
    >
        <slot />
        <!-- 触发元素插槽 -->

        <view v-if="visible" ref="tooltipRef" id="tooltip" class="tooltip" :class="position" :style="tooltipStyle">
            <view class="tooltip-arrow" :style="{ left: arrowOffset + 'px' }" :class="position"></view>
            <view class="tooltip-content" :style="contentStyle">{{ content }}</view>
        </view>
    </view>
</template>

<script>
export default {
    props: {
        content: String, //内容
        fontSize: {
            // 字体大小
            type: Number,
            default: 14,
        },
        theme: {
            // 主题
            type: String, // ['dark', 'white']
            default: 'dark',
        },
        isLongPress: {
            // 是否长按
            type: Boolean,
            default: false,
        },
        contentStyle: {
            // 卡片内容样式
            type: String,
            default: '',
        },
        longPressThreshold: {
            // 长按延时触发
            type: Number,
            default: 500,
        },
    },
    data() {
        return {
            pressTimer: null,
            hasEnded: false,
            visible: false,
            tooltipStyle: '', // 控制 tooltip 定位样式
            position: 'top',
            arrowOffset: 0,
            pressTimer: null,
            added: false,
        };
    },
    methods: {
        onStart(e) {
            // 普通点击触发
            if (!this.isLongPress && this.added) {
                this.hide(e);
                setTimeout(() => {
                    this.added = false;
                }, 500);
            }

            // 长按模式
            if (this.isLongPress) {
                this.pressTimer = setTimeout(() => {
                    this.show(e);
                }, this.longPressThreshold || 500);
            }
        },
        onEnd(e) {
            clearTimeout(this.pressTimer);

            // 普通点击触发（不是长按模式，或者长按未到时间）
            if (!this.isLongPress && !this.added) {
                this.show(e);
                setTimeout(() => {
                    this.added = true;
                }, 500);
            }

            // 如果是长按模式但未触发 show（如短按中断），主动关闭
            if (this.isLongPress) {
                this.hide();
            }
        },
        onCancel() {
            if (this.pressTimer) {
                clearTimeout(this.pressTimer);
            }
        },
        async show(e) {
            this.visible = true;
            await this.$nextTick(() => {
                const clientX = e.clientX || e.changedTouches[0].clientX;
                this.useTooltipPosition(clientX);
            });
        },
        hide() {
            this.visible = false;
        },
        getRects() {
            return new Promise((resolve) => {
                const query = uni.createSelectorQuery().in(this);
                query.select('#tooltip').boundingClientRect();
                query.select('#trigger').boundingClientRect();
                query.exec((res) => {
                    resolve({
                        tipRect: res[0],
                        triggerRect: res[1],
                    });
                });
            });
        },
        useTooltipPosition(clientX) {
            this.getRects().then(async ({ tipRect, triggerRect }) => {
                const systemInfo = uni.getSystemInfoSync();
                const navbarHeight = systemInfo.windowTop;
                const viewport = {
                    width: systemInfo.safeArea.width,
                    height: systemInfo.safeArea.height,
                };

                // 箭头偏移：点击点（clientX）相对于 tooltip 左边缘的位置
                let arrowOffset = clientX - tipRect.left;

                // 限制箭头不要太靠边：距左右边缘最小12px
                const minOffset = 12;
                const maxOffset = tipRect.width - 12;

                if (arrowOffset < minOffset) {
                    arrowOffset = minOffset;
                } else if (arrowOffset > maxOffset) {
                    arrowOffset = maxOffset;
                }

                this.arrowOffset = arrowOffset;

                // 尝试方向，按优先级选取能容纳的方向
                const directions = ['top', 'bottom', 'right', 'left'];
                let chosen = 'top';
                for (const dir of directions) {
                    if (dir === 'top' && triggerRect.top >= tipRect.height + 10) {
                        chosen = 'top';
                        break;
                    } else if (dir === 'bottom' && viewport.height - triggerRect.bottom >= tipRect.height + 10) {
                        chosen = 'bottom';
                        break;
                    } else if (dir === 'right' && viewport.width - triggerRect.right >= tipRect.width + 10) {
                        chosen = 'right';
                        break;
                    } else if (dir === 'left' && triggerRect.left >= tipRect.width + 10) {
                        chosen = 'left';
                        break;
                    }
                }
                if (this.theme === 'white') {
                    this.position = `${chosen} white`;
                } else {
                    this.position = chosen;
                }

                // 设置样式
                const padding = 8;
                const left = triggerRect.left + triggerRect.width / 2 - tipRect.width / 2;
                const top = triggerRect.top - tipRect.height - padding;
                this.tooltipStyle = {
                    position: 'fixed',
                    maxWidth: '80vw',
                    left: `${Math.max(8, Math.min(left, viewport.width - tipRect.width - 8))}px`,
                    fontSize: `${this.fontSize}px`,
                    top:
                        chosen === 'top'
                            ? `${triggerRect.top + navbarHeight - tipRect.height - padding}px`
                            : chosen === 'bottom'
                            ? `${triggerRect.bottom + navbarHeight + padding}px`
                            : `${triggerRect.top + triggerRect.height / 2 - tipRect.height / 2 + navbarHeight}px`,
                    transform:
                        chosen === 'right'
                            ? `translateX(${triggerRect.width / 2 + padding}px)`
                            : chosen === 'left'
                            ? `translateX(-${tipRect.width + padding}px)`
                            : 'none',
                };
            });
        },
    },
};
</script>

<style lang="scss" scoped>
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: scale(0.95);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}
.tooltip-wrapper {
    display: inline-block;
    position: relative;
}

.tooltip {
    background-color: #333;
    color: white;
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 14px;
    z-index: 9999;
    word-break: break-word;
    white-space: normal;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    animation: fadeIn 0.2s ease-out;
    opacity: 0;
    animation-fill-mode: forwards;
}
.tooltip {
    position: fixed;
    background-color: #333;
    color: white;
    padding: 10px 14px;
    border-radius: 6px;
    z-index: 9999;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    max-width: 80vw;
    display: flex;
    align-items: center;
    justify-content: center;
}
.tooltip-content {
    text-align: center;
}

.tooltip.white {
    background-color: #ffffff;
    color: #333333;
    box-shadow: 0 4px 12px rgba(43, 108, 176, 0.25); /* 蓝色阴影 */
    font-weight: 500;
    // font-size: 14px;
}

.tooltip-arrow {
    width: 0;
    height: 0;
    position: absolute;

    &.top {
        bottom: -6px;
        left: 50%;
        transform: translateX(-50%);
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 6px solid #333;
    }

    &.bottom {
        top: -6px;
        left: 50%;
        transform: translateX(-50%);
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-bottom: 6px solid #333;
    }

    &.left {
        right: -6px;
        top: 50%;
        transform: translateY(-50%);
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-left: 6px solid #333;
    }

    &.right {
        left: -6px;
        top: 50%;
        transform: translateY(-50%);
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-right: 6px solid #333;
    }
}

.tooltip-arrow.white {
    width: 0;
    height: 0;
    position: absolute;

    &.top {
        bottom: -6px;
        left: 50%;
        transform: translateX(-50%);
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 6px solid #fff;
        /* 只在主边添加阴影 */
        filter: drop-shadow(0 -2px 4px rgba(43, 108, 176, 0.25));
    }

    &.bottom {
        top: -6px;
        left: 50%;
        transform: translateX(-50%);
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-bottom: 6px solid #fff;
        filter: drop-shadow(0 2px 4px rgba(43, 108, 176, 0.25));
    }

    &.left {
        right: -6px;
        top: 50%;
        transform: translateY(-50%);
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-left: 6px solid #fff;
        filter: drop-shadow(-2px 0 4px rgba(43, 108, 176, 0.25));
    }

    &.right {
        left: -6px;
        top: 50%;
        transform: translateY(-50%);
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-right: 6px solid #fff;
        filter: drop-shadow(2px 0 4px rgba(43, 108, 176, 0.25));
    }
}
</style>
